#pragma once
#include "../UIElement.h"
#include "../IUIProgressElement.h"

class UIProgressBar : public UIElement, public IUIProgressElement
{
public:
	UIProgressBar();
	UIProgressBar(float xPos, float yPos);
	UIProgressBar(float xPos, float yPos, float width, float height);

	// Draws the element on the screen and has to be called between graphics.BeginDraw() and graphics.EndDraw()
	void __stdcall Draw(Graphics* graphics);

	Color ProgressColor = Color::Cyan;
	bool RoundedCorners = true;
	float RoundCornerRadiusX = 4, RoundCornerRadiusY = 4;

	// Set enabled state of the element
	void SetEnabled(bool state)
	{
		this->enabled = state;
		if (state)
		{
			color.a = normalAlpha;
			ProgressColor.a = normalAlpha;
		}
		else
		{
			color.a = 36;
			ProgressColor.a = 36;
		}
	}

	// Fades the element out over given period of time in miliseconds
	void __stdcall FadeOut(int time)
	{
		std::thread fadeout_thread([this, &time]
		{
			Color currentColor = color;
			float currentAlpha = currentColor.a;
			if (currentAlpha == 0) { currentAlpha = 1; }
			int sleepIntervals = time / (int)currentAlpha;
			for (int i = (int)currentAlpha; i > 0; i--)
			{
				currentColor.a--;
				color = currentColor;

				Color newProgressColor = ProgressColor;
				newProgressColor.a = currentColor.a;
				ProgressColor = newProgressColor;

				Sleep(sleepIntervals);
			}
			Visible = false;
		});
		fadeout_thread.join();
	}

	// Fades the element in over given period of time in miliseconds until the needed alpha value is reached
	void __stdcall FadeIn(int time, int finalAlpha = 255)
	{
		int sleepInterval = 0;
		if (finalAlpha < color.a) return; // invalid alpha state
		int delta = finalAlpha - color.a;
		if (delta == 0)
		{
			sleepInterval = time;
		}
		else
		{
			sleepInterval = time / delta;
		}

		if (finalAlpha >= 255)
			finalAlpha = 254;

		std::thread fadein_thread([this, sleepInterval, finalAlpha] {
			Visible = true;
			for (int i = color.a; i <= finalAlpha; i++)
			{
				Sleep(sleepInterval);
				uint8_t val = (uint8_t)i;
				color.a = val;


				Color newProgressColor = ProgressColor;
				newProgressColor.a = color.a;
				ProgressColor = newProgressColor;

				normalAlpha = color.a;
			}
		});
		fadein_thread.detach();
	}

private:
	float __stdcall calculateProgressBarWidth(float value);
	float m_PreviousValue = Value;
};
